package com.edu.service.impl;

import com.api.course.CourseClient;
import com.api.order.OrderClient;
import com.edu.config.MyWXConfig;
import com.edu.entity.HfdClassSkuInfo;
import com.edu.entity.HfdOrderInfo;
import com.edu.service.IPayService;
import com.edu.vo.Result;
import com.edu.websocket.Websocket;
import com.github.wxpay.sdk.WXPayRequest;
import com.github.wxpay.sdk.WXPayUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

@Service
@RefreshScope
public class WXPayService implements IPayService {

    @Autowired(required = false)
    private OrderClient orderClient;

    @Autowired(required = false)
    private CourseClient courseClient;

    @Value("${weixin.notifyUrl}")
    private String notifyUrl;

    //支付；得到支付二维码返回页面
    @Override
    public Result pay(String orderId) {

        try {
            //查询订单信息
            HfdOrderInfo hfdOrderInfo = orderClient.findOrderById(orderId);

            //获取课程价格
            HfdClassSkuInfo hfdClassSkuInfo = courseClient.findClassSkuInfoBySkuId(hfdOrderInfo.getSkuId());
            Integer totalFee = hfdClassSkuInfo.getMoney() / 1000;

            //调用微信的统一下单接口，下单
            Map map = WXPay(orderId, totalFee, notifyUrl);

            Map data = new HashMap();
            data.put("payUrl", map.get("code_url"));
            data.put("errCode", map.get("err_code"));
            data.put("totalFee", totalFee);
            data.put("orderId", orderId);

            return new Result(true, 80011, "微信下单成功", data);

        } catch (Exception e) {
            e.printStackTrace();
            return new Result(false, 80010, "微信下单失败");
        }

    }

    //获取订单状态
    @Override
    public Result status(String orderId) throws Exception {

        //1.构建配置对象
        MyWXConfig config = new MyWXConfig();
        //2.封装请求参数
        Map params = new HashMap();
        params.put("appid", config.getAppID());
        params.put("mch_id", config.getMchID());
        params.put("out_trade_no", orderId);
        params.put("nonce_str", WXPayUtil.generateNonceStr());
        //3.map转xml
        String requestXML = WXPayUtil.generateSignedXml(params, config.getKey());
        //4:发送请求WXPayRequest request = new WXPayRequest(config);
        WXPayRequest request = new WXPayRequest(config);
        String resXml = request.requestWithoutCert("/pay/orderquery", UUID.randomUUID().toString(), requestXML, false);
        //5.响应结果转map集合
        Map<String, String> resMap = WXPayUtil.xmlToMap(resXml);
        //6.获取支付状态

        return new Result(true, 80021, "success", resMap.get("trade_state"));
    }


    //关闭订单
    @Override
    public Result close(String orderId) throws Exception {

        //1.构建配置对象
        MyWXConfig config = new MyWXConfig();
        //2.封装请求对象
        Map params = new HashMap();
        params.put("appid", config.getAppID());
        params.put("mch_id", config.getMchID());
        params.put("out_trade_no", orderId);
        params.put("nonce_str", WXPayUtil.generateNonceStr());
        //3.map转xml
        String requestXML = WXPayUtil.generateSignedXml(params, config.getKey());
        //4:发送请求WXPayRequest request = new WXPayRequest(config);
        WXPayRequest request = new WXPayRequest(config);
        String resXml = request.requestWithoutCert("/pay/closeorder", UUID.randomUUID().toString(), requestXML, false);
        //5.响应结果转map集合
        Map<String, String> resMap = WXPayUtil.xmlToMap(resXml);
        //6.获取关闭结果
        if ("SUCCESS".equals(resMap.get("result_code"))) {
            return new Result(true, 80031, "success");
        } else {

            return new Result(false, 80030, "fail");
        }

    }

    @Override
    public String notify(HttpServletRequest request) {

        System.out.println("微信支付系统成功回调");
        InputStream inputStream;

        try {
            inputStream = request.getInputStream();
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len = 0;
            while ((len = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, len);
            }
            outputStream.close();
            inputStream.close();
            String result = new String(outputStream.toByteArray(), "utf-8");

            //对xml进行解析 map
            //对xml进行解析 map
            Map<String, String> map = WXPayUtil.xmlToMap(result);
            //验证签名
            boolean signatureValid = WXPayUtil.isSignatureValid(map,
                    new MyWXConfig().getKey());

            //获取订单id
            String orderId = map.get("out_trade_no");

            if (signatureValid && "SUCCESS".equals(map.get("result_code"))) {
                //修改订单状态
                HfdOrderInfo hfdOrderInfo = new HfdOrderInfo();
                hfdOrderInfo.setOrderId(orderId);
                hfdOrderInfo.setStatus("1");
                orderClient.update(hfdOrderInfo);

                //添加用户课程中间表
                HfdOrderInfo order = orderClient.findOrderById(orderId);
                orderClient.addUserVideo(order);

                //通知前端
                Websocket.sendMessageToClient(orderId, "success");

            }
            Map data = new HashMap();
            data.put("return_code", "SUCCESS");
            data.put("return_msg", "OK");

            //map转xml
            String returnXml = WXPayUtil.generateSignedXml(data, new MyWXConfig().getKey());

            return returnXml;
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }

    }


    //调用微信统一下单接口方法
    private Map WXPay(String orderId, Integer fee, String notifyUrl) throws Exception {

        //1.构建配置
        MyWXConfig config = new MyWXConfig();

        //2.封装请求数据
        Map<String, String> requestParams = new HashMap<String, String>();
        requestParams.put("appid", config.getAppID());
        requestParams.put("mch_id", config.getMchID());
        requestParams.put("nonce_str", WXPayUtil.generateNonceStr());
        requestParams.put("body", "猴辅导");
        requestParams.put("out_trade_no", orderId);//业务系统订单号
        requestParams.put("total_fee", fee + "");//订单金额
        requestParams.put("spbill_create_ip", "127.0.0.1");
        requestParams.put("notify_url", notifyUrl);
        requestParams.put("trade_type", "NATIVE");

        //3.将map转xml串
        String requestParamsXml = WXPayUtil.generateSignedXml(requestParams, config.getKey());

        //4.发请求
        WXPayRequest request = new WXPayRequest(config);
        String resultXml = request.requestWithoutCert("/pay/unifiedorder", UUID.randomUUID().toString(), requestParamsXml, false);

        System.out.println(resultXml);


        //5.将resultXml转map集合
        final Map<String, String> resultMap = WXPayUtil.xmlToMap(resultXml);

        return resultMap;
    }

}
